/*
 * LensKit, an open-source toolkit for recommender systems.
 * Copyright 2014-2017 LensKit contributors (see CONTRIBUTORS.md)
 * Copyright 2010-2014 Regents of the University of Minnesota
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package org.grouplens.lenskit.test;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.lenskit.LenskitConfiguration;
import org.lenskit.eval.traintest.AlgorithmInstanceBuilder;
import org.lenskit.eval.traintest.SimpleEvaluator;
import org.lenskit.util.table.Table;

import java.io.IOException;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.*;

/**
 * A test suite that does cross-validation of an algorithm.
 */
public abstract class CrossfoldTestSuite extends ML100KTestSuite {
    @Rule
    public TemporaryFolder workDir = new TemporaryFolder();

    protected abstract void configureAlgorithm(LenskitConfiguration config);

    protected abstract void checkResults(Table table);

    @Test
    public void testAlgorithmAccuracy() throws IOException {
        SimpleEvaluator evalCommand = new SimpleEvaluator();
        evalCommand.getExperiment().setThreadCount(4);
        evalCommand.setWorkDir(workDir.newFolder("data").toPath());
        AlgorithmInstanceBuilder algo = new AlgorithmInstanceBuilder();
        configureAlgorithm(algo.getConfig());
        evalCommand.addAlgorithm(algo.build());

        evalCommand.addDataSet(source, 5, 0.2);
        addExtraConfig(evalCommand);

        Table result = evalCommand.execute();
        assertThat(result, notNullValue());
        checkResults(result);
    }

    public void addExtraConfig(SimpleEvaluator eval) {
        /* do nothing */
    }
}
